package com.ygqh.baby.service.impl;

import com.ygqh.baby.cache.RedisCache;
import com.ygqh.baby.po.YgProduct;
import com.ygqh.baby.po.YgStock;
import com.ygqh.baby.service.RedisCacheEvictService;
import com.ygqh.baby.service.YgProductService;
import com.ygqh.baby.service.wechat.service.WeixinGoodService;
import com.ygqh.baby.solr.ProductSolrApi;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class RedisCacheEvictServiceImpl implements RedisCacheEvictService {
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private YgProductService ygProductService;
    @Autowired
    private WeixinGoodService weixinGoodService;
    @Autowired
    private ProductSolrApi productSolrApi;

    private static final ExecutorService executorService = Executors.newFixedThreadPool(2);

    private final static String PRODUCT_DETAIL_PREFIX_PID = "product:detail_pid_";
    private final static String PRODUCT_YJD_DETAIL_PREFIX_PID = "product:yjd_detail_pid_";
    private final static String STOCK_PREFIX_PCODE = "stock:pcode_";

    @Override
    public void evictAboutProduct(Long pid, String productCode, String method) {
        // product.updateSaleStatus ,product.updatePreSaleDate
        // ,product.updateSalesPrice
        executorService.execute(() -> {
            List<String> keys = new ArrayList<String>();
            keys.add(PRODUCT_DETAIL_PREFIX_PID + pid);
            keys.add(PRODUCT_YJD_DETAIL_PREFIX_PID + pid);
            if ("product.saveOrUpdate".equals(method)) {
                // 商品新增、修改 需将 商品详情页 detail接口缓存移除，库存缓存移除
                keys.add(STOCK_PREFIX_PCODE + productCode);
            }
            redisCache.evictBatch(keys);
            // 更新solr
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            generateStaticPages.reviewPage(pid);
            productSolrApi.updateProductSolr(pid);
            // 更新好物圈
            weixinGoodService.importProduct(pid);
        });
    }

    @Override
    public void evictProductByGroup(Long groupId, String method) {
        executorService.execute(() -> {
            List<String> keys = new ArrayList<String>();
            List<Long> pids = new ArrayList<Long>();
            List<Map<String, Object>> list = ygProductService.findProductByGroupId(0L, groupId);
            for (Map<String, Object> map : list) {
                Long pid = (Long) map.get("id");
                keys.add(PRODUCT_DETAIL_PREFIX_PID + pid);
                keys.add(PRODUCT_YJD_DETAIL_PREFIX_PID + pid);
                pids.add(pid);
            }
            redisCache.evictBatch(keys);
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            generateStaticPages.reviewPage(pids.toArray(new Long[pids.size()]));
            // 更新solr
            productSolrApi.updateProductSolr(pids);
            // 更新好物圈
            weixinGoodService.importProductByIds(pids);
        });
    }

    @Override
    public void evictProductByStock(List<YgStock> stockList, String method) {
        if (CollectionUtils.isEmpty(stockList)) {
            return;
        }

        executorService.execute(() -> {
            List<String> skuCodes = stockList.stream().map(s -> s.getSkuCode()).collect(Collectors.toList());
            List<Map<String, Object>> list = ygProductService.findPidAndPcodeBySkuCodes(skuCodes.toArray(new String[skuCodes.size()]));

            List<String> keys = new ArrayList<String>();
            for (Map<String, Object> map : list) {
                Long pid = (Long) map.get("id");
                String pCode = (String) map.get("productCode");
                keys.add(PRODUCT_DETAIL_PREFIX_PID + pid);
                keys.add(PRODUCT_YJD_DETAIL_PREFIX_PID + pid);
                keys.add(STOCK_PREFIX_PCODE + pCode);
            }

            redisCache.evictBatch(keys);
        });
    }

    @Override
    public void evictProductByIds(Long[] productIds) {
        if (productIds == null || productIds.length == 0) {
            return;
        }
        List<Long> pids = Arrays.asList(productIds);
        executorService.execute(() -> {
            List<String> keys = new ArrayList<>(pids.size());
            pids.forEach(pid -> {
                keys.add(PRODUCT_DETAIL_PREFIX_PID + pid);
                keys.add(PRODUCT_YJD_DETAIL_PREFIX_PID + pid);
            });
            redisCache.evictBatch(keys);
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 更新solr
            productSolrApi.updateProductSolr(pids);
            // 更新好物圈
            weixinGoodService.importProductByIds(pids);
        });
    }

    @Override
    public void evictProductByIds(String[] productIds) {
        if (productIds == null || productIds.length == 0) {
            return;
        }
        Long[] longArr = (Long[]) ConvertUtils.convert(productIds, Long.class);
        this.evictProductByIds(longArr);
    }

    @Override
    public void evictProductByName(String distProductName) {
        List<YgProduct> listByName = ygProductService.findListByName(distProductName);
        this.evictProductByIds(listByName.stream().map(YgProduct::getId).toArray(Long[]::new));

    }

}
